"""
Logging infrastructure for specification fixing.

Provides centralized logging configuration and utilities
for all components in the specification fixer module.
"""

import logging
import logging.handlers
import os
from pathlib import Path
from typing import Optional
from datetime import datetime


def get_logger(name: str, level: Optional[str] = None) -> logging.Logger:
    """
    Get a configured logger instance.

    Args:
        name: Logger name (usually __name__)
        level: Optional log level override

    Returns:
        Configured logger instance
    """
    if name not in _loggers:
        logger = logging.getLogger(name)
        _configure_logger(logger, level)
        _loggers[name] = logger
    return _loggers[name]


def setup_logging(config: Optional[dict] = None) -> None:
    """
    Setup global logging configuration.

    Args:
        config: Logging configuration dictionary
    """
    global _logging_configured

    if _logging_configured:
        return

    # Default configuration
    default_config = {
        "level": "INFO",
        "file": "logs/specification_fixer.log",
        "max_file_size_mb": 10,
        "backup_count": 5,
        "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    }

    if config:
        default_config.update(config)

    # Create logs directory
    log_file = Path(default_config["file"])
    log_file.parent.mkdir(exist_ok=True)

    # Configure root logger
    root_logger = logging.getLogger()
    root_logger.setLevel(getattr(logging, default_config["level"]))

    # Remove existing handlers
    for handler in root_logger.handlers[:]:
        root_logger.removeHandler(handler)

    # Create formatters
    formatter = logging.Formatter(default_config["format"])

    # Console handler
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)
    console_handler.setFormatter(formatter)
    root_logger.addHandler(console_handler)

    # File handler with rotation
    file_handler = logging.handlers.RotatingFileHandler(
        log_file,
        maxBytes=default_config["max_file_size_mb"] * 1024 * 1024,
        backupCount=default_config["backup_count"],
        encoding='utf-8'
    )
    file_handler.setLevel(getattr(logging, default_config["level"]))
    file_handler.setFormatter(formatter)
    root_logger.addHandler(file_handler)

    _logging_configured = True


def get_log_level(level_str: str) -> int:
    """Convert string log level to logging constant."""
    return getattr(logging, level_str.upper(), logging.INFO)


def log_function_call(func):
    """Decorator to log function calls."""
    def wrapper(*args, **kwargs):
        logger = get_logger(func.__module__)
        logger.debug(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        try:
            result = func(*args, **kwargs)
            logger.debug(f"{func.__name__} completed successfully")
            return result
        except Exception as e:
            logger.error(f"{func.__name__} failed with error: {e}")
            raise
    return wrapper


def log_performance(operation_name: str):
    """Decorator to log performance metrics."""
    def decorator(func):
        def wrapper(*args, **kwargs):
            logger = get_logger(func.__module__)
            start_time = datetime.now()
            try:
                result = func(*args, **kwargs)
                end_time = datetime.now()
                duration = (end_time - start_time).total_seconds()
                logger.info(f"{operation_name} completed in {duration:.2f} seconds")
                return result
            except Exception as e:
                end_time = datetime.now()
                duration = (end_time - start_time).total_seconds()
                logger.error(f"{operation_name} failed after {duration:.2f} seconds: {e}")
                raise
        return wrapper
    return decorator


class ContextLogger:
    """Context manager for logging operation context."""

    def __init__(self, logger: logging.Logger, operation: str, level: int = logging.INFO):
        self.logger = logger
        self.operation = operation
        self.level = level
        self.start_time = None

    def __enter__(self):
        self.start_time = datetime.now()
        self.logger.log(self.level, f"Starting {self.operation}")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        end_time = datetime.now()
        duration = (end_time - self.start_time).total_seconds()

        if exc_type is None:
            self.logger.log(self.level, f"Completed {self.operation} in {duration:.2f}s")
        else:
            self.logger.error(f"Failed {self.operation} after {duration:.2f}s: {exc_val}")

        return False  # Don't suppress exceptions


# Private module variables
_loggers: dict[str, logging.Logger] = {}
_logging_configured = False


def _configure_logger(logger: logging.Logger, level: Optional[str] = None) -> None:
    """Configure individual logger."""
    if level:
        logger.setLevel(get_log_level(level))
    else:
        logger.setLevel(logging.DEBUG)  # Default to debug for module loggers

    # Prevent propagation to avoid duplicate logs
    logger.propagate = False


# Initialize logging on module import
try:
    setup_logging()
except Exception:
    # If setup fails, use basic configuration
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    )